/*
    发布者客户端联调
*/

#include "../../src/client/connection.hpp"
#include "../../src/common/logger.hpp"

int main()
{
    // 1. 创建异步工作线程
    mq::AsyncWorker::AsyncWorkerPtr async_worker_ptr = std::make_shared<mq::AsyncWorker>();

    // 2. 创建连接对象
    mq::Connection::ConnectionPtr connection_ptr = std::make_shared<mq::Connection>(async_worker_ptr, 8080, "127.0.0.1");

    // 3. 打开信道，并获取对象
    mq::Channel::ChannelPtr channel_ptr = connection_ptr->openChannel();

    // 4. 通过信道发起服务
    // 4.1 声明交换机
    // bool ret = channel_ptr->declareExchanger("exchanger1", mq::ExchangerType::FANOUT, true, false, {}); // 广播类型
    // bool ret = channel_ptr->declareExchanger("exchanger1", mq::ExchangerType::DIRECT, true, false, {}); // 直接交换
    bool ret = channel_ptr->declareExchanger("exchanger1", mq::ExchangerType::TOPIC, true, false, {}); // 主题交换
    if(!ret)
        INF_LOG("declare exchanger failed\n");

    // 4.2 声明队列
    ret = channel_ptr->declareMsgQueue("queue1", true, false, false, {});
    if(!ret)
        INF_LOG("declare msg queue1 failed\n");
    ret = channel_ptr->declareMsgQueue("queue2", true, false, false, {});
    if(!ret)
        INF_LOG("declare msg queue2 failed\n");
    
    // 4.3 绑定队列
    ret = channel_ptr->bind("exchanger1", "queue1", "queue1");
    if(!ret)
        INF_LOG("bind msg queue1 failed\n");
    ret = channel_ptr->bind("exchanger1", "queue2", "news.music.#");
    if(!ret)
        INF_LOG("bind msg queue2 failed\n");
        
    // 4.4 发布消息
    for(int i = 0; i < 10; i++)
    {
        std::string routing_key = i % 2 ? "queue1" : "news.music.pop";
        mq::BasicProperties properties;
        properties.set_id(mq::UUIDHelper::uuid());
        properties.set_delivery_mode(mq::DeliveryMode::DURABLE);
        properties.set_routing_key(routing_key);
        ret = channel_ptr->publish("exchanger1", &properties, "hello world " + std::to_string(i));
        if(!ret)
            INF_LOG("publish failed, i = %d\n", i);
        else
            INF_LOG("publish success, i = %d\n", i);
    }

    // 5. 关闭信道
    ret = connection_ptr->closeChannel(channel_ptr);
    if(!ret)
        INF_LOG("close channel failed\n");
    return 0;
}